import { _decorator, Component, EventTouch, Label, Node, Prefab, Sprite, SpriteFrame, Tween, tween, UITransform, Widget } from 'cc';
import { PoolManager } from 'db://assets/Scripts/Framework/Managers/PoolManager';
import { EasingType } from 'db://assets/Scripts/Framework/Utils/TweenUtil';
import { GamerBackPack } from '../GamerBackpack';
import { Ammo } from '../Items/Ammo';
import { InGameManager } from '../Managers/InGameManager';
import { PlayerController } from '../PlayerController';
import { ControlUI } from './ControlUI';
import { ItemUI } from './ItemUI';
import { BundleManager } from 'db://assets/Scripts/Framework/Managers/BundleManager';
const { ccclass, property } = _decorator;

@ccclass('PackUI')
export class PackUI extends Component {

    private static instance: PackUI;
    public static get Instance(): PackUI {
        return this.instance;
    }

    @property(UITransform)
    itemView: UITransform;

    @property(UITransform)
    dropNode: UITransform;

    @property(Node)
    packCapacity: Node;

    @property(Node)
    armors: Node;

    @property(Node)
    guns: Node;

    @property(Node)
    touchNode: Node;

    @property(Prefab)
    itemPrefab: Prefab;

    @property([SpriteFrame])
    gunBgSfs: SpriteFrame[] = [];

    widget: Widget;
    itemContent: Node;
    pack: GamerBackPack;
    touchTarget: Object;

    protected onLoad(): void {
        PackUI.instance = this;
        this.widget = this.getComponent(Widget);
        this.itemContent = this.itemView.node.children[0].children[0];
    }

    start() {
        this.pack = PlayerController.Instance.backPack;
        this.TouchInit();
    }

    update(deltaTime: number) {

    }

    OpenPack() {
        this.Init();
        Tween.stopAllByTarget(this.widget);
        tween(this.widget)
            .to(0.5, { right: 0 }, { easing: EasingType.circOut })
            .start();
    }

    ClosePack() {
        Tween.stopAllByTarget(this.widget);
        tween(this.widget)
            .to(0.5, { right: -1400 }, { easing: EasingType.circIn })
            .start();
    }

    Init() {
        this.ArmorInit();
        this.GunInit();
        this.ItemInit();
    }

    ArmorInit() {
        let Armors = this.pack.armors;
        if (Armors.length == 0) {
            for (let i = 0; i < this.armors.children.length; i++) {
                const element = this.armors.children[i];
                element.active = false;
            }
        }
        else {
            for (let i = 0; i < Armors.length; i++) {
                const element = Armors[i];
                this.armors.children[i].active = element != null;
                if (!element) continue;
                BundleManager.GetBundle("MainPack").load(element.sfUrl, SpriteFrame, (err, data) => {
                    let sprite = this.armors.children[i].children[0].getComponent(Sprite);
                    if (sprite.spriteFrame != data) sprite.spriteFrame = data;
                });
                this.armors.children[i].children[1].getComponent(Sprite).fillRange = 1 - (element.durability / element.maxDurability);
                this.armors.children[i].children[2].getComponent(Sprite).spriteFrame = ControlUI.Instance.levelSfs[element.level];
            }
        }
    }

    GunInit() {
        let guns = this.pack.guns;
        let data = InGameManager.itemsJson;
        for (let i = 0; i < this.guns.children.length; i++) {
            const element = this.guns.children[i];
            const gun = guns[i == 2 ? 0 : i + 1];
            element.getComponent(Sprite).spriteFrame = this.gunBgSfs[gun == this.pack.CurWeapon ? 1 : 0];
            element.children[0].active = gun != null;
            if (!gun) continue;
            BundleManager.GetBundle("MainPack").load(gun.weaponSfUrl, SpriteFrame, (err, data) => {
                let sprite = element.children[0].children[0].getComponent(Sprite);
                if (sprite.spriteFrame != data) sprite.spriteFrame = data;
            });
            let ammos = this.pack.items.filter((value, index, array) => { if (value instanceof Ammo && value.type == gun.type) return value; });
            let ammoNum = 0;
            ammos.forEach(element => { ammoNum += element.num; });
            element.children[0].children[1].getComponent(Label).string = gun.itemName;
            element.children[0].children[2].getComponent(Label).string = `[${data.Ammo[gun.type].name}]`;
            element.children[0].children[3].getComponent(Label).string = `${gun.curAmmo}/${ammoNum}`;
            for (let j = 4; j < element.children[0].children.length; j++) {
                const element2 = element.children[0].children[j];
                element2.active = gun.accessModules[j - 4];
                if (!element2.active) continue;
                element2.children[0].active = gun.modules[j - 4] == null;
                if (gun.modules[j - 4]) BundleManager.GetBundle("MainPack").load(gun.modules[j - 4].sfUrl, SpriteFrame, (err, data) => {
                    let sprite = element2.children[1].getComponent(Sprite);
                    if (sprite.spriteFrame != data) sprite.spriteFrame = data;
                });
                else element2.children[1].getComponent(Sprite).spriteFrame = null;
            }
        }
    }

    ItemInit() {
        let itemNum = this.pack.items.length;
        let itemLimit = this.pack.MaxItems;
        this.packCapacity.children[0].getComponent(Sprite).fillRange = itemNum / itemLimit;
        this.packCapacity.children[1].getComponent(Label).string = `${itemNum}/${itemLimit}`;
        for (let i = 0; i < this.pack.items.length; i++) {
            const element = this.pack.items[i];
            let item = this.itemContent.children[i];
            if (!item) item = PoolManager.GetNodeByPrefab(this.itemPrefab, this.itemContent);
            item.getComponent(ItemUI).Init(element);
        }
        let items = this.itemContent.children.slice(this.pack.items.length);
        items.forEach(element => { PoolManager.PutNode(element); });
    }

    TouchInit() {
        for (let i = 0; i < this.guns.children.length; i++) {
            const element = this.guns.children[i];
            for (let j = 4; j < element.children[0].children.length; j++) {
                const element2 = element.children[0].children[j];
                element2.on(Node.EventType.TOUCH_START, this.TouchStart, this);
                element2.on(Node.EventType.TOUCH_MOVE, this.TouchMove, this);
                element2.on(Node.EventType.TOUCH_END, this.TouchEnd, this);
                element2.on(Node.EventType.TOUCH_CANCEL, this.TouchEnd, this);
            }
        }
    }

    TouchStart(event: EventTouch) {
        if (this.touchTarget) return;
        this.touchTarget = this;
        let target: Node = event.target;
        let pos = event.getUILocation().toVec3();
        this.touchNode.setWorldPosition(pos);
        this.touchNode.getComponent(Sprite).spriteFrame = target.children[1].getComponent(Sprite).spriteFrame;
    }

    TouchMove(event: EventTouch) {
        if (this.touchTarget != this) return;
        let pos = event.getUILocation();
        this.touchNode.setWorldPosition(pos.toVec3());
    }

    TouchEnd(event: EventTouch) {
        if (this.touchTarget != this) return;
        this.touchTarget = null;
        let pos = event.getUILocation();
        let target: Node = event.target;
        if (this.touchNode.getComponent(Sprite).spriteFrame) {
            let gunNum = target.parent.parent.getSiblingIndex();
            let gun = this.pack.guns[gunNum == 2 ? 0 : gunNum + 1];
            let module = gun.modules[target.getSiblingIndex() - 4];
            let change = false;
            if (this.itemView.getBoundingBoxToWorld().contains(pos)) {
                this.pack.UnequipModule(module, gun);
                change = true;
            }
            else if (this.dropNode.getBoundingBoxToWorld().contains(pos)) {
                this.pack.UnequipModule(module, gun, true);
                change = true;
            }
            else {
                for (let i = 0; i < this.guns.children.length; i++) {
                    if (i == gunNum) continue;
                    const element = this.guns.children[i].getComponent(UITransform);
                    if (element.getBoundingBoxToWorld().contains(pos)) {
                        let targetGun = this.pack.guns[i == 2 ? 0 : i + 1];
                        if (targetGun && targetGun.accessModules[module.type]) {
                            this.pack.ReequipModule(module, gun, targetGun);
                            change = true;
                            break;
                        }
                    }
                }
            }
            if (change) {
                this.GunInit();
                this.ItemInit();
            }
            this.touchNode.getComponent(Sprite).spriteFrame = null;
        }
    }

}